#include "rand.h"

#include <stdlib.h>

#include "tick.h"

void sc_rand_init(struct sc_rand *rand) {
    sc_tick seed = sc_tick_now(); // microsecond precision

    // 用移位的方式初始化一个随机数种子,具体的移动方法看单元测试
    rand->xsubi[0] = (seed >> 32) & 0xFFFF;
    rand->xsubi[1] = (seed >> 16) & 0xFFFF;
    rand->xsubi[2] = seed & 0xFFFF;
}

uint32_t sc_rand_u32(struct sc_rand *rand) {
    // jrand returns a value in range [-2^31, 2^31]
    // conversion from signed to unsigned is well-defined to wrap-around
    // jrand48 函数是一个生成伪随机数序列的函数，并且它是可重入的，即可以在多个线程中同时调用而不会出现冲突
    
    // 这不是windows体系下的函数
    // https://ftp.gnu.org/pub/old-gnu/Manuals/glibc-2.2.3/html_node/libc_388.html
    return jrand48(rand->xsubi);
}

uint64_t sc_rand_u64(struct sc_rand *rand) {
    uint32_t msb = sc_rand_u32(rand);
    uint32_t lsb = sc_rand_u32(rand);
    // 左移后合并成一个长整型的随时数
    return ((uint64_t) msb << 32) | lsb;
}
